Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

86장. X-Ray — 분산 트레이싱

이 장에서 말하고자 하는 것

마이크로서비스에서 한 사용자 요청이 통과하는 경로는 길다.

사용자 → CloudFront → API Gateway → ALB
    → orders → users (호출)
            → payments (호출)
                → DB · 외부 결제 API

운영 중 “이 한 요청은 어디서 1.5초가 걸렸나?” 가 자주 묻는 질문이다.

이 답을 주는 도구가

분산 트레이싱(Distributed Tracing)

이고, AWS의 옵션이

AWS X-Ray

다.


1. Trace · Segment · Subsegment

Trace (한 요청의 전체 이야기)
 ├─ Segment: API Gateway
 ├─ Segment: orders 서비스
 │   ├─ Subsegment: DB query
 │   └─ Subsegment: users 서비스 호출
 │       └─ Segment: users 서비스
 │           └─ Subsegment: DB query
 └─ Segment: payments 서비스
     └─ Subsegment: 외부 결제 API

각 구간이 얼마나 걸렸는지 시각적으로 펼쳐진다.


2. trace_id — 한 요청을 따라가는 끈

요청이 시작될 때 발급되는 ID.

Trace ID: 1-abcd1234-...

모든 다운스트림 호출에 이 ID가 헤더로 전달된다.

X-Amzn-Trace-Id: Root=1-abcd1234-...

각 서비스의 로그에도 trace_id를 같이 기록한다.

로그 + 트레이스 + 메트릭이 trace_id 로 한 줄에 묶인다
이게 운영 관측성의 핵심 연결고리


3. AWS X-Ray SDK · OpenTelemetry

X-Ray SDK

AWS 전용. 비교적 단순.

OpenTelemetry (OTel) + AWS Distro (ADOT)

업계 표준. AWS · Datadog · Honeycomb 등 어디든 보낼 수 있다.

새 프로젝트는 거의 항상 OpenTelemetry 부터
AWS 종속을 줄이고 다른 백엔드로 옮기기 쉬움


4. 자동 계측 vs 수동 계측

자동 계측

프레임워크 / 라이브러리가 알아서 트레이스를 만든다.

  • HTTP 요청
  • DB 쿼리
  • AWS SDK 호출
  • HTTP 클라이언트

수동 계측

비즈니스 로직 안에서 명시적으로 구간을 만든다.

tracer.startActiveSpan("calculate-shipping", (span) => {
  span.setAttribute("order.weight", weight);
  ...
  span.end();
});

자동 계측을 먼저, 비즈니스적으로 의미 있는 구간만 수동 추가


5. ECS · API Gateway · ALB와의 통합

  • API Gateway — 한 줄로 X-Ray 활성화
  • ALB — 자동 trace_id 전파 헤더
  • ECS / Fargate — X-Ray 데몬 사이드카 또는 OTel Collector
  • Lambda — Tracing 옵션을 켜면 자동

활성화는 어렵지 않다 — 코드는 SDK 한 줄


6. Service Map

X-Ray가 자동으로 그려주는 서비스 의존성 그래프.

[client] → [API Gateway] → [orders]
                            ├─ → [users]
                            ├─ → [payments] → [외부 API]
                            └─ → [RDS]
  • 평균 지연 · 에러율을 노드에 표시
  • 어느 노드가 느린지 / 에러를 만드는지 한눈에

7. 우리 서비스에서

모든 서비스가 OpenTelemetry로 계측
  ↓ OTLP
[ADOT Collector 사이드카]
  ↓
[X-Ray] (운영)
[추가로 Datadog/Honeycomb 도 옵션]

각 서비스 로그에 trace_id 필수 필드
  • p95 가 튀는 시점 → X-Ray에서 trace 한 건 클릭 → 어느 구간에서 느렸나 즉시 파악

8. 직접 확인해보기

ECS Task에 X-Ray 사이드카 추가

{
  "name": "xray-daemon",
  "image": "public.ecr.aws/xray/aws-xray-daemon:latest",
  "essential": false,
  "portMappings": [{ "containerPort": 2000, "protocol": "udp" }]
}

애플리케이션 코드 (Node.js, X-Ray SDK)

const AWSXRay = require("aws-xray-sdk");
const express = require("express");

const app = express();
app.use(AWSXRay.express.openSegment("orders"));
app.use(routes);
app.use(AWSXRay.express.closeSegment());

OpenTelemetry 권장 패턴

import { NodeSDK } from "@opentelemetry/sdk-node";
import { AwsXrayIdGenerator } from "@opentelemetry/id-generator-aws-xray";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-grpc";

const sdk = new NodeSDK({
  idGenerator: new AwsXrayIdGenerator(),
  traceExporter: new OTLPTraceExporter({ url: "http://localhost:4317" }),
});
sdk.start();

9. 코드로는 이렇게 생겼다 — Terraform (API Gateway X-Ray)

resource "aws_apigatewayv2_stage" "prod" {
  api_id      = aws_apigatewayv2_api.main.id
  name        = "$default"
  auto_deploy = true

  default_route_settings {
    detailed_metrics_enabled = true
    logging_level            = "INFO"
    throttling_burst_limit   = 5000
    throttling_rate_limit    = 10000
  }
}

# X-Ray 활성화는 통합 단계에서 설정
# Terraform 에서는 IAM 권한과 ADOT Collector 사이드카 추가가 핵심

10. 이렇게 쓰면 망한다 — 안티패턴

안티패턴 1. trace_id 를 로그에 안 넣는다

트레이스와 로그가 분리돼 운영에서 서로를 못 찾는다.

모든 로그 한 줄에 trace_id 필수

안티패턴 2. 샘플링을 안 한다

모든 요청을 트레이싱하면 비용 폭증. X-Ray 기본은 1초당 1건 + 5%.

운영 부하에 맞춰 샘플링 조정

안티패턴 3. 외부 호출은 안 추적한다

가장 느린 구간이 외부 결제 API · S3 같은 곳에 있는데 보이지 않는다.

AWS SDK · HTTP 클라이언트 자동 계측 켠다

안티패턴 4. 트레이스가 있는데 안 본다

운영 회의나 사고 보고에서 추측만 한다.

사용자 영향 큰 사고는 항상 트레이스로 시작


11. 한 줄로 정리

X-Ray는 한 요청의 여행을 시각화하는 도구이며,
trace_id 가 로그 · 메트릭 · 트레이스를 한 줄로 묶는 끈이다


12. 이 장의 핵심 정리

  1. 분산 트레이싱은 한 요청의 다중 서비스 흐름을 따라간다.
  2. Trace ID가 운영 관측성의 핵심 연결고리다.
  3. OpenTelemetry + AWS Distro (ADOT) 가 새 프로젝트의 표준이다.
  4. 자동 계측을 먼저, 의미 있는 구간만 수동 추가.
  5. Service Map으로 의존성과 지연을 한눈에 본다.
  6. 모든 로그 한 줄에 trace_id 를 넣는 게 가장 큰 차이를 만든다.